package com.bosssoft.cloud.wechat.infrastructure.interceptor;

import com.bosssoft.cloud.wechat.common.infra.handler.SmsHandler;
import com.bosssoft.cloud.wechat.infrastructure.annotation.VerifyCode;
import com.bosssoft.cloud.wechat.infrastructure.constant.VerifyCodeConsts;
import com.bosssoft.cloud.wechat.infrastructure.enums.ErrEnum;
import com.bosssoft.cloud.wechat.infrastructure.exception.BusinessException;
import com.bosssoft.cloud.wechat.infrastructure.exception.SystemException;
import com.bosssoft.cloud.wechat.infrastructure.util.Assert;
import com.bosssoft.cloud.wechat.infrastructure.util.VerifyCodeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * 验证码校验拦截器
 *
 * @author wcy create on 2021/7/23 18:11 下午
 */
@Slf4j
@Component
public class VerifyCodeInterceptor implements HandlerInterceptor {

    @Resource
    private SmsHandler smsHandler;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (handler instanceof HandlerMethod) {
            VerifyCode anno = ((HandlerMethod) handler).getMethodAnnotation(VerifyCode.class);
            // 方法上有VerifyCode注解，进行验证码校验
            if (anno != null) {
                // 验证码，不要把它移到if (anno != null)外
                String code = request.getParameter(anno.name());
                // 校验code是否为空
                if (code == null) {
                    // 如果code为空，且必填，返回验证码为空错误
                    if (anno.required()) throw new BusinessException(ErrEnum.A0411);
                    // 如果code为空，且非必填，跳过验证
                    return true;
                }
                // 根据VerifyCode.type()，判断处理的验证码类型
                switch (anno.type()) {
                    // 校验图片验证码
                    case VerifyCodeConsts.IMAGE:
                        HttpSession session = request.getSession();
                        VerifyCodeUtil.verifyCode(session, code);
                        break;
                    // 校验手机数字验证码
                    case VerifyCodeConsts.PHONE:
                        String[] others = anno.others();
                        Assert.isTrue(others.length > 0, ErrEnum.B0400, "VerifyCode注解使用错误,请在others中添加phone的入参名!");
                        String phone = null;
                        for (String pname : others) {
                            phone = request.getParameter(pname);
                            if (phone != null) break;
                        }
                        smsHandler.verifyCode(phone, code);
                        break;
                    default:
                        throw new SystemException(ErrEnum.B0400, "请在VerifyCode中填入正确的验证码类型！");
                }
            }
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) {
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
    }
}
